SciChart WPF 3D Charts > Advanced 3D Chart APIs > The SceneEntity API > Adding Text to a 3D Chart
Adding Text to a 3D Chart

Using the BaseSceneEntity API it is possible to draw text on the chart at specific X,Y,Z locations.

The class TextSceneEntity is included in our example code, in Add Geometry to a 3D Scene example, but is included for your convenience below.

 

TextSceneEntity.cs
Copy Code
/// <summary>
/// A class to demonstrate a 3D Text Elements added to the SciChart3D Scene. Created using our BaseSceneEntity and Font3D APIs
/// </summary>
public class TextSceneEntity : BaseSceneEntity
{
    private readonly Color _textColor;
    private readonly TextDisplayMode _textDisplayMode;
    Font3D _font;
    public string Text { get; set; }
    [TypeConverter(typeof(StringToVector3TypeConverter))]
    public Vector3 Location { get; set; }
    public double RotationAngle { get; set; }
    static TextSceneEntity()
    {
        SCRTDllLoader.InitNativeLibs();
    }
    public TextSceneEntity(string text, Color textColor, Vector3 location, TextDisplayMode textDisplayMode = TextDisplayMode.FacingCameraAlways, int fontSize = 8, string fontFamily = "Arial")
    {
        Text = text;
        _textColor = textColor;
        Location = location;
        _textDisplayMode = textDisplayMode;
        _font = new Font3D(fontFamily, (uint) fontSize);
        // Set requires SeletionId to false to exclude this item from selection, tooltips and also 
        // prevent issues with maximum number of selectable meshes 
        this.RequiresSelectionId = false;
    }
    /// <summary>
    /// Determines whether this instance is transparent. When True SciChart internally
    /// </summary>
    /// <returns></returns>
    public override bool IsTransparent()
    {
        return _textColor.A < 255;
    }
    /// <summary>
    /// Called when the 3D Engine wishes to render this element. This is where geometry must be drawn to the 3D scene
    /// </summary>
    /// <param name="e">The <see cref="IRenderPassInfo3D" /> containing parameters for the current render pass.</param>
    public override void RenderScene(IRenderPassInfo3D e)
    {
        if (_font == null) return;
        var currentCamera = RootSceneEntity != null ? RootSceneEntity.Viewport3D.CameraController : null;
        switch (_textDisplayMode)
        {
            case TextDisplayMode.Default:
                {
                    // Just display text
                    _font.Begin();
                    _font.AddText(Text, _textColor, Location.X, Location.Y, Location.Z);
                    _font.End();
                    break;
                }
            case TextDisplayMode.FacingCameraAlways:
                {
                    if (currentCamera == null)
                        goto case TextDisplayMode.Default;
                    // Display billboarded text using camera vectors                
                    Vector3 cameraFwd = currentCamera.Forward;
                    Vector3 cameraUp = currentCamera.Up;
                    // Compute a side vector
                    Vector3 cameraSide = cameraFwd ^ cameraUp;
                    cameraSide.Normalize();
                    // Compute orthogonal up vector
                    cameraUp = cameraSide ^ cameraFwd;
                    cameraUp.Normalize();
                    // Display text billboarded using camera side, up vectors (text will always face camera) 
                    _font.BeginBillboard(cameraSide, cameraUp);
                    _font.AddText(Text, _textColor, Location.X, Location.Y, Location.Z);
                    _font.End();
                    break;
                }
            case TextDisplayMode.SacreenSpace:
                {
                    // Screen space text 2D
                    _font.BeginScreenSpace((float) RotationAngle, Location.X, Location.Y);
                    _font.AddText(Text, _textColor, Location.X, Location.Y, Location.Z);
                    _font.EndScreenSpace();
                    break;
                }
            default:
                throw new ArgumentOutOfRangeException();
        }
    }
    /// <summary>
    /// Releases unmanaged and - optionally - managed resources.
    /// </summary>
    public override void Dispose()
    {
        _font.SafeDispose();
        _font = null;
        base.Dispose();
    }
    /// <summary>
    /// Called when the 3D Engine wishes to update the geometry in this element. This is where we need to cache geometry before draw.
    /// </summary>
    /// <param name="e">The <see cref="IRenderPassInfo3D" /> containing parameters for the current render pass.</param>
    public override void UpdateScene(IRenderPassInfo3D e)
    {
    }

    /// <summary>
    /// Performs selection on this entity, setting the IsSelected flag to True or False on the specified <see cref="VertexId">Vertex Ids</see>
    /// </summary>
    /// <param name="isSelected">if set to <c>true</c> the vertices become .</param>
    /// <param name="vertexIds">The vertex ids.</param>
    public override void PerformSelection(bool isSelected, List<VertexId> vertexIds)
    {
    }
}

 

These text entities are then added to the chart via the SciChart3DSurface.Viewport3D.RootEntity property.

 

Adding TextSceneEntities to the Chart
Copy Code
// Add some text labels to the scene 
var textA = new TextSceneEntity("Teeny Block", Color.FromArgb(255, 0, 225, 0), new Vector3(75f, 100f, 75f), TextDisplayMode.FacingCameraAlways, 9, "Segoe UI");

var textB = new TextSceneEntity("Big Block", Color.FromArgb(255, 255, 255, 255), new Vector3(-50f,200f,-50f), TextDisplayMode.FacingCameraAlways, 10, "Tahoma");
sciChart3DSurface.Viewport3D.RootEntity.Children.Add(textA);
sciChart3DSurface.Viewport3D.RootEntity.Children.Add(textB);

 

It should be noted the text is added at various positions defined by Vector3 structs. It should be noted that the coordinates are in World Coordinates. Conversion between World and Data Coordinates is performed by the axis, and discussed here.